package com.liuwei.spring.cloud.junit.leetcode.hots;

import com.liuwei.spring.cloud.common.utils.Jackson;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Slf4j
public class MergeIntervals {
    /**
     * 以数组 intervals 表示若干个区间的集合，其中单个区间为 intervals[i] = [starti, endi] 。
     * 请你合并所有重叠的区间，并返回一个不重叠的区间数组，该数组需恰好覆盖输入中的所有区间
     * @param args
     */
    public static void main(String[] args) {
        int[][] intervals = new int[][]{{1,3},{2,6},{8,10},{15,18}};
        MergeIntervals solution = new MergeIntervals();
        int[][] result = solution.merge(intervals);
        log.info("result:{}", Jackson.toJSONString(result));
    }

    public int[][] merge(int[][] intervals) {
        List<int[]> values = new ArrayList<>();
        for (int i = 0; i < intervals.length; i++) {
            values.add(intervals[i]);
        }
        values.sort(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                int a = o1[0];
                int b = o2[0];
                return a-b;
            }
        });
        log.info("list:{}", Jackson.toJSONString(values));
        List<int[]> response = new ArrayList<>();
        int[] lastMerged = null;
        for (int i = 0; i < values.size(); i++) {
            int[] current = values.get(i);
            if(i==(values.size()-1)){
                if(lastMerged==null){
                    response.add(current);
                    continue;
                }else{
                    response.add(lastMerged);
                    continue;
                }
            }
            int[] next = values.get(i+1);

            if(lastMerged!=null){
                current = lastMerged;
            }
            Result result = mergeTwoInterval(current,next);
            if(result.success){
                lastMerged = result.merged;
                log.info("lastMerged:{}", Jackson.toJSONString(lastMerged));
            }else{
                lastMerged = null;
                response.add(current);
            }
        }
        int[][] ends = new int[response.size()][];
        for (int i = 0; i < response.size(); i++) {
            ends[i] = response.get(i);
        }
        return ends;
    }

    public Result mergeTwoInterval(int[] a,int[]b){
        Result result = new Result();
        result.setA(a);
        result.setB(b);
        int minA = a[0];
        int maxA = a[1];
        int minB = b[0];
        int maxB = b[1];
        if(minB<minA){
            if(maxB<minA){
                result.setSuccess(false);
            }
            if(maxB>=minA && maxB<=maxA){
                int[] merged = new int[2];
                result.setSuccess(true);
                merged[0] = minB;
                merged[1] = maxA;
                result.setMerged(merged);
            }
            if(maxB>maxA){
                int[] merged = new int[2];
                result.setSuccess(true);
                merged[0] = minB;
                merged[1] = maxB;
                result.setMerged(merged);
            }
        }
        if(minB>=minA && minB<=maxA){
            if(maxB>=minA && maxB<=maxA){
                int[] merged = new int[2];
                result.setSuccess(true);
                merged[0] = minA;
                merged[1] = maxA;
                result.setMerged(merged);
            }
            if(maxB>maxA){
                int[] merged = new int[2];
                result.setSuccess(true);
                merged[0] = minA;
                merged[1] = maxB;
                result.setMerged(merged);
            }
        }
        if(minB>maxA){
            result.setSuccess(false);
        }
        return result;
    }

    public static class Result{
        int[] a;
        int[] b;
        boolean success;
        int[] merged;
        public int[] getA() {
            return a;
        }

        public void setA(int[] a) {
            this.a = a;
        }

        public int[] getB() {
            return b;
        }

        public void setB(int[] b) {
            this.b = b;
        }

        public boolean isSuccess() {
            return success;
        }

        public void setSuccess(boolean success) {
            this.success = success;
        }

        public int[] getMerged() {
            return merged;
        }

        public void setMerged(int[] merged) {
            this.merged = merged;
        }
    }
}
